package com.zdy.im.user.facade;

import com.sixeco.framework.common.enums.SysResultCodeEnum;
import com.sixeco.framework.common.enums.TbStatusEnum;
import com.sixeco.framework.http.exception.SystemRuntimeException;
import com.sixeco.framework.http.message.ParamMessage;
import com.zdy.im.conf.ImServerSettings;
import com.zdy.im.enums.ImResultCodeEnum;
import com.zdy.im.user.ImErrorMsg;
import com.zdy.im.user.dto.request.ImUserFriendShipRequestDto;
import com.zdy.im.user.dto.request.UserInfoRequestDto;
import com.zdy.im.user.dto.response.*;
import com.zdy.im.user.service.*;
import com.zdy.im.user.vo.response.InitShowResponseVo;
import com.zdy.im.user.vo.response.Oauth2TokenDto;
import com.zdy.im.user.vo.response.UserInfoShowResponseExt;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.security.Principal;
import java.util.*;


/**   
 * @Title: UserInfoFacade.java
 * @Author 作者 : zdy
 * @CreateDate 创建时间: 2021-02-30
 * @version V1.0  
 *  <pre>
 * 修改记录
 *    修改后版本:     修改人：  修改日期:     修改内容:
 * </pre>
 * @Description: TODO(说明) 对象缓存统一模板实现类;  
 */
 
@Component
public class InitFacade {

	@Autowired
	private UserInfoService userInfoService;
	@Autowired
	private ImUserFriendShipService imUserFriendShipService;
	@Autowired
	private ImRoomUserShipService imRoomUserShipService;
	@Autowired
	private ImRoomInfoService imRoomInfoService;
	@Autowired
	private ImUserGroupInfoService imUserGroupInfoService;
	@Autowired
	private TokenEndpoint tokenEndpoint;
	@Autowired
	private ImServerSettings imServerSettings;
	/**
     * 初始化
	 * @param userId
     * @return
     */
	public InitShowResponseVo init(long userId){
		//个人用户信息
		UserInfoResponseDto userInfoResponse = userInfoService.getUserInfoById(userId);
		if(userInfoResponse == null){
			throw new SystemRuntimeException(ImResultCodeEnum.IM_USER_NOT_EXIST);
		}

		//查询某用户，所有好友
		List<ImUserFriendShipResponseDto> friendList = imUserFriendShipService.selectListByUserId(userId);
		Set<Long> userIds = new HashSet<>();
		if(!CollectionUtils.isEmpty(friendList)){
			friendList.forEach(e ->{
				userIds.add(e.getFriendId());
			});
			//用户头像
			Map<Long, UserInfoResponseDto> userMap = userInfoService.getUserInfoByIds( userIds);
			friendList.forEach(e->{
				if(!CollectionUtils.isEmpty(userMap) && userMap.get(e.getFriendId()) != null){
					e.setFriendHeadImg(userMap.get(e.getFriendId()).getHeadImg());
				}
			});
		}


		//查询某用户，所有群
		Set<Long> ids = new HashSet<>();
		List<ImRoomUserShipResponseDto> roomList = imRoomUserShipService.selectListByUserId(userId);
		if(!CollectionUtils.isEmpty(roomList)){
			roomList.forEach(e->{
				ids.add(e.getRoomId());
			});
		}
		List<ImRoomInfoResponseDto> rooms = imRoomInfoService.selectListByIds(ids);
		InitShowResponseVo vo = InitShowResponseVo.build()
				.toRooms(rooms)//用户添加的群
				.toFriends(friendList)//用户添加的好友
				.toMe(UserInfoShowResponseExt.build().clone(userInfoResponse));//个人信息
		return vo;
	}

	public Oauth2TokenDto customerInit(Principal principal){
		Oauth2TokenDto oauth2TokenDto ;
		try{
			String ip = ParamMessage.getRequestMessage().getIp();
			//客服userId
			long userId = 1;
			String password = "123456";

			//
			String wsUrl = imServerSettings.getWs() +"?cmd=1&userId="+userId+"&token=";
			//客服信息
			UserInfoResponseDto customer = userInfoService.getUserInfoById(userId);
			if(customer == null){
				//返回token信息
				throw new SystemRuntimeException(ImResultCodeEnum.IM_CUSTOMER_NOT_EXIST);
			}
			//判断该用户是否存在
			UserInfoResponseDto me = userInfoService.getUserInfoByLoginName(ip);
			if(me != null){
				//走登录，返回token
				oauth2TokenDto = getToken( ip, password, userId, principal);
				return oauth2TokenDto.toCustomer(UserInfoShowResponseExt.build().clone(customer))
						.toMe(UserInfoShowResponseExt.build().clone(me))
						.toWsUrl(wsUrl+oauth2TokenDto.getAccess_token());
			}

			//注册用户
			String finalSecret = "{bcrypt}" + new BCryptPasswordEncoder().encode(password);
			UserInfoRequestDto userInfoRequestDto = UserInfoRequestDto.build()
					.toUserName(StringUtils.isEmpty(ip) ? "":ip.substring(8,ip.length()))
					.toLoginName(ip)
					.toMobile("")
					.toPassword(finalSecret)//BCryptPasswordEncoder方法采用SHA-256 +随机盐+密钥对密码进行加密
					.toHeadImg(imServerSettings.getDefHeadImg())//默认头像
					.toStatus(TbStatusEnum.ENABLE.index()).toRemarks("游客用户");
			UserInfoResponseDto userInfoResponseDto = userInfoService.saveUserInfo(userInfoRequestDto);
			if(userInfoResponseDto == null){
				throw new SystemRuntimeException(SysResultCodeEnum.SYS_USER_SAVE_FAIL);
			}

			//获取默认组
			ImUserGroupInfoResponseDto imUserGroupInfoResponseDto = imUserGroupInfoService.selectDefGroupOne(userId);
			if(imUserGroupInfoResponseDto == null){
				throw new SystemRuntimeException(SysResultCodeEnum.SYS_PARAM_ERROR.formatMsg(ImErrorMsg.User.USER_GROUP_NOT_NULL));
			}
			//获取好友，分组的最大排序sort
			ImUserFriendShipResponseDto imFriendShip = imUserFriendShipService.selectOneByUserIdAndGroupId( userId, imUserGroupInfoResponseDto.getId());
			int sort = 0;
			if(imFriendShip != null){
				sort = imFriendShip.getSort() + 1;
			}

			//创建客服与游客关系
			ImUserFriendShipRequestDto imUserFriendShipRequestDto = ImUserFriendShipRequestDto.build()
					.toUserId(userId)//客服id
					.toFriendId(userInfoResponseDto.getId())
					.toUserGroupName(imUserGroupInfoResponseDto.getGroupName())
					.toUserGroupId(imUserGroupInfoResponseDto.getId())
					.toSort(sort)
					.toStatus(TbStatusEnum.ENABLE.index())
					.toFriendRemarks(userInfoResponseDto.getUserName());
			imUserFriendShipService.saveImUserFriendShip(imUserFriendShipRequestDto);

			//走登录，返回token
			oauth2TokenDto = getToken( ip, password, userId, principal);

			return oauth2TokenDto.toCustomer(UserInfoShowResponseExt.build().clone(customer))
					.toMe(UserInfoShowResponseExt.build().clone(userInfoResponseDto))
					.toWsUrl(wsUrl+oauth2TokenDto.getAccess_token());
		}catch (Exception e){
			e.printStackTrace();
			throw  new SystemRuntimeException(SysResultCodeEnum.SYS_TOKEN_NULL);
		}
	}

	public Oauth2TokenDto getToken( String ip, String password, long userId ,Principal principal){
		Map<String, String> parameters = new HashMap<>();
		try {
			//走登录，返回token
			parameters.put("client_id", "v-client");
			parameters.put("client_secret", "v-client-ppp");
			parameters.put("grant_type", "password");
			parameters.put("scope", "select");
			parameters.put("username", ip);
			parameters.put("password", password);

			OAuth2AccessToken oAuth2AccessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
			Oauth2TokenDto oauth2TokenDto = Oauth2TokenDto.build()
					.toAccess_token(oAuth2AccessToken.getValue())
					.toRefresh_token(oAuth2AccessToken.getRefreshToken().getValue())
					.toExpires_in(oAuth2AccessToken.getExpiresIn())
					.toToken_type(oAuth2AccessToken.getTokenType())
					.toUser_id(userId);
		return oauth2TokenDto;
		}catch(Exception e){
			e.printStackTrace();
			throw  new SystemRuntimeException(SysResultCodeEnum.SYS_TOKEN_NULL);
		}
	}
}
